//
//  Invocation.hpp
//  Simulation
//
//  Created by Christopher Kemsley on 2/28/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#ifndef Simulation_Invocation_hpp
#define Simulation_Invocation_hpp

#include "Object.hpp"

NamespaceBegin






// Abstract way for objects to make callback functions
struct	Invocation : public Object
{
	virtual void	invoke () const = 0 ;
};






template <typename TargetType>
struct	ObjectInvocation : public Invocation
{
	typedef void	(TargetType::*CallbackMethod)	(  ) ;
	
	
	// Target & Method cannot be nil
	static Invocation*	create		( TargetType * inTarget , CallbackMethod inMethod ) ;
	static Invocation*	invocation	( TargetType * inTarget , CallbackMethod inMethod ) ;
	
	
private:
	virtual void		invoke () const ;
	
	TargetType		*	mTarget ;
	CallbackMethod		mMethod ;
	
	
	// Target & Method cannot be nil
	ObjectInvocation	( TargetType * inTarget , CallbackMethod inMethod ) ;
} ;






template <typename TargetType,typename ContextType=void*>
struct	ObjectContextInvocation : public Invocation
{
	typedef void	(TargetType::*CallbackMethod)	( ContextType const & context ) ;
	
	
	// Target & Method cannot be nil
	static Invocation*	create		( TargetType * inTarget , CallbackMethod inMethod , ContextType const & inContext=0 ) ;
	static Invocation*	invocation	( TargetType * inTarget , CallbackMethod inMethod , ContextType const & inContext=0 ) ;
	
	
private:
	virtual void		invoke () const ;
	
	TargetType		*	mTarget ;
	ContextType const	mContext ;
	CallbackMethod		mMethod ;
	
	
	// Target & Method cannot be nil
	ObjectContextInvocation	( TargetType * inTarget , CallbackMethod inMethod , ContextType const & inContext=0 ) ;
} ;






#include "Invocation.hxx"
NamespaceEnd
#endif
